package org.sciom

object ScIomClosureInvoker {
  val activate = (self: ScIomObject, target: ScIomObject, locals: ScIomObject, m: ScIomMessage, slotContext: ScIomObject) => {
    if(self.isInstanceOf[ScIomClosureInvoker]) {
      val selfData = self.asInstanceOf[ScIomClosureInvoker]
      val t = selfData.typeTag

      if(t != null && t != target.tag) {
        // TODO: error

//		char *a = (char *)IoTag_name(t);
//		char *b = (char *)IoTag_name(IoObject_tag(target));
//		IoState_error_(IOSTATE, m, "CFunction defined for type %s but called on type %s", a, b);
      }

      selfData.func(target,locals,m)
    } else {
      // TODO: ERROR
      null
    }
  }
}

class ScIomClosureInvoker(state: ScIomState, _func: (ScIomObject, ScIomObject, ScIomMessage) => ScIomObject, _typeTag: ScIomTag, funcName: String) extends ScIomObject(state) {
  def this(state: ScIomState) = {
    this(state, ScIomObject.selfFunc, null, null)
  }

  val func = _func
  val typeTag = _typeTag

  activatable = true

  override def allocate() : ScIomClosureInvoker = {
    if(typeTag == null) {
      return new ScIomClosureInvoker(state)
    } else {
      return new ScIomClosureInvoker(state, func, typeTag, funcName)
    }
  }

  tag = new ScIomTag(state, "CFunction", ScIomObject.rawClone)
  tag.activateFunc = ScIomClosureInvoker.activate

  var uniqueName = state.symbolWithString(funcName)
}
